/**
 * String类
 *      1.常用构造方法
 *      2.字符串的比较
 *      3.字符串查找
 *      4.转化
 *      5.替换
 *      6.字符串拆分
 *      7.字符串截取
 *      8.字符串的不可变性
 */
class Student {
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "name: " + name + " 年龄: " + age;
    }
}
public class Test {
    /**
     * 字符串修改
     *      +=(效率低下(会重复创建对象),且也没有改变,只是指向了新的对象)
     *      StringBuilder
     *      StringBuffer
     * @param args
     */
    public static void main(String[] args) {
        long start = System.currentTimeMillis();//获取时间戳
        String s = "";
        for(int i = 0; i < 10000; ++i){
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 10000; ++i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }
    public static void main18(String[] args) {
        /**
         * 字符串不可变性:内容不可改变
         * 注意:
         *      1.不可改变原因(设计时设计的):两个final(类不可继承 引用对象不可改变) 一个private(不提供修改方法,无法改变)
         *      2.对原来字符串的修改都是创建了一个新的对象,改变的都是新的对象
         */
    }
    /**
     * trim方法
     *      返回一个去掉字符串左右空格,保留中间空格字符串
     */
    public static void main17(String[] args) {
        String str = "        sngoang    oiaso     ";
        String ret = str.trim();
        System.out.println(str);
        System.out.println(ret);
    }
    /**
     * 字符串截取
     * subString
     * @param args
     */
    public static void main16(String[] args) {
        /**
         * 字符串截取
         * substring(int beginIndex)->从下标位置开始截取
         * substring(int beginIndex,int endIndex)->[)
         */
        String str = "hello";
        System.out.println(str.substring(2));//llo
        System.out.println(str.substring(2,4));//ll
    }
    /**
     *字符串拆分
     * split(字符串)
     * split(字符串,拆分次数)
     */
    public static void main15(String[] args) {
        /**
         * split(字符串)->全部拆分
         * split(字符串,拆分次数)->如果超过最大拆分次数,全部拆分完即可
         */
        String str = "hello world hello bit";
        String[] array1 = str.split(" ");
        for(int i = 0;i < array1.length;i++) {
            System.out.println(array1[i]);
        }

        String[] array2 = str.split(" ",2);
        for(int i = 0;i < array2.length;i++) {
            System.out.println(array2[i]);
        }
        System.out.println("====================");
        /**
         * 特殊的分割
         *      1.使用* + . |,需要通过"\\"进行转义
         *      2.使用\,需要写为"\\\\"
         *      3.需要使用多个分割符,写成"分割符 | 分割符"
         */

        String str2 = "192.168.1.1";
        String[] result = str2.split("\\.") ;
        for(String s: result) {
            System.out.println(s);
        }

        String str3 = "192\\.168\\.1\\.1";
        String[] array3 = str3.split("\\\\\\.");
        for(String s: array3) {
            System.out.println(s);
        }

        String str4 = "name = zhangSan&age = 30";
        String[] array4 = str4.split(" |&");
        for(String s: array4) {
            System.out.println(s);
        }

        System.out.println("===============");

        String str5 = "name=zhangSan&age=18";
        String[] array5 = str5.split("&");
        for (String x:array5) {
            String[] xx = x.split("=");
            for (String ret : xx) {
                System.out.println(ret);
            }
        }
    }
    /**
     * 替换
     */
    public static void main14(String[] args) {
        /**
         * 替换
         *      1.replace(字符/字符串,字符/字符串),将前面的字符/字符串替换为后面的字符/字符串
         *      2.replaceAll(字符串,字符串),将前面字符串替换为后面字符串
         *      3.replaceFirst(字符串,字符串),将第一次出现的字符串,替换为后面的字符串
         */
        String str = "absfsgoagoababse";
        String ret1 = str.replace('a','q');
        System.out.println(ret1);
        String ret2 = str.replace("ab","qqqqqqq");
        System.out.println(ret2);

        String ret3 = str.replaceAll("ab","uuuuuuu");
        System.out.println(ret3);
        String ret4 = str.replaceFirst("ab","kkkkkkkkkkkkk");
        System.out.println(ret4);

        System.out.println(str);//不改变原来对象
    }
    /**
     * 格式化->format
     * @param args
     * 字符串.format(格式符,对应的值)
     */
    public static void main13(String[] args) {
        String str = String.format("%d-%d-%d",2024,6,15);
        System.out.println(str);
    }
    /**
     * 字符串转数组
     *      1.字符串转数组
     *      2.数组转字符串
     */
    public static void main12(String[] args) {
        //1.
        String str = "hello";
        char[] ch = str.toCharArray();
        for(char c:ch) {
            System.out.print(c + " ");
        }
        System.out.println();
        //2.
        String str2 = new String(ch);
        System.out.println(str2);
        String str3 = String.valueOf(ch);
        System.out.println(str2);
    }
    /**
     * 转化
     *      1.数值和字符串转化
     *      2.大小写转换
     */
    public static void main11(String[] args) {
        /**
         * 大小写转换
         *      1.大写转小写
         *      2.小写转大写
         * 注:字符串的改变均是创建新的对象,不是在原本对象基础上修改的
         */
        String str1 = "hello";
        String ret1 = str1.toUpperCase();
        System.out.println(ret1);

        String str2 = "HELLO";
        String ret2 = str2.toLowerCase();
        System.out.println(ret2);
    }
    public static void main10(String[] args) {
        /**
         * 数值和字符串转化
         *      1.数值转字符串
         *      2.字符串转数值
         * 需要转成什么就包装类型(引用类型).valueOf(待转换类型变量名)
         */
        int a = 123;
        //支持对象变为String
        System.out.println(String.valueOf(new Student("张三",20)));
        System.out.println(String.valueOf(a));

        String str = "123";
        int b = Integer.valueOf(str);
        System.out.println(b + 1);
    }
    /**
     * 字符串查找
     * @param args
     *      1.charAt
     *      2.indexOf
     *      3.lastIndexOf
     */
    public static void main9(String[] args) {
        /**
         * lastIndexOf
         *      1.lastIndexOf(int ch)->从后往前查找ch,存在,返回第一次出现的下标,不存在,返回-1
         *      2.lastIndexOf(int ch,int fromIndex)->从fromIndex下标从后往前查找,存在则返回第一次出现的下标,不存在,返回-1
         *      3.lastIndexOf(String str)->从后往前查找str,存在,返回第一次出现的下标,不存在,返回-1
         *      3.lastIndexOf(String str,int fromIndex)->从fromIndex下标从后往前查找str,存在,返回第一次出现的下标,不存在,返回-1
         */
        String str = "hello";
        System.out.println(str.lastIndexOf('l'));//3
        System.out.println(str.lastIndexOf('l',2));//2
        System.out.println(str.lastIndexOf("llo"));//2
        System.out.println(str.lastIndexOf("llo",4));//2

    }
    public static void main8(String[] args) {
        /**
         * indexOf()
         *      1.indexOf(int ch)->根据字符,返回字符串中,第一次返回字符的下标,不存在返回-1
         *      2.indexOf(int ch(查找字符),int fromIndex(从哪个下标开始找))->从fromIndex开始查找ch,返回第一次出现下标
         *      不存在返回-1
         *      3.indexOf(String str)->查找字符串中str第一次出现的首字母下标,不存在返回-1
         *      4.indexOf(String str,int fromIndex)->从fromIndex下标查找字符串str,并返回首字母第一次出现的下标,不存在返回-1
         */
        String str = "hello";
        System.out.println(str.indexOf('l'));//2
        System.out.println(str.indexOf('l',3));//3
        System.out.println(str.indexOf("llo"));//2
        System.out.println(str.indexOf("llo",3));//-1
    }
    public static void main7(String[] args) {
        /**
         * char charAt(int index)->根据下标返回对应的字符,越界报错
         *      字符串.charAt(下标)
         */
        String str = "hello";
        System.out.println(str.charAt(1));
//        System.out.println(str.charAt(5));//error
    }
    /**
     * 字符串的比较
     * @param args
     *      1.==直接比较,
     *      2.equals()比较,判断是否相同
     *      3.compareTo()比较,判断大小
     *      4.compareToIg
     */
    public static void main6(String[] args) {
        /**
         * int 字符串.compareToIgnoreCase(字符串)
         *      忽略大小写,相等返回0,不等返回差值
         */
        String str1 = new String("hello");
        String str2 = new String("hello");
        System.out.println(str1.compareToIgnoreCase(str2));//0

        String str3 = new String("hello");
        String str4 = new String("hz");
        System.out.println(str3.compareToIgnoreCase(str4));//-21 e - z

        String str5 = new String("hello");
        String str6 = new String("HELLO");
        System.out.println(str5.compareToIgnoreCase(str6));//0
    }
    public static void main5(String[] args) {
        /**
         * int 字符串.compareTo(字符串),比较字典序
         *      相等返回0,不等返回不同字符ASCII差值
         */
        String str1 = new String("hello");
        String str2 = new String("hello");
        System.out.println(str1.compareTo(str2));//0

        String str3 = new String("hello");
        String str4 = new String("hz");
        System.out.println(str3.compareTo(str4));//-21 e - z
    }
    public static void main4(String[] args) {
        /**
         * boolean 字符串.equals(字符串)比较
         *      判断是否相等,按照字节序进行比较(重写Object内equals方法,逐个比较字符大小)
         *      相等则返回true,不等则返回false
         */
        String str1 = new String("hello");
        String str2 = new String("hello");
        System.out.println(str1.equals(str2));
    }
    public static void main3(String[] args) {
        /**
         * ==,只能比较使用""直接进行赋值,如果通过new创建的就必然不相等
         * 可以比较使用""原因: 堆中存在常量池,进行创建时,会先在常量池中查看是否存在,存在就直接引用,不存在再创建,所以可以比较
         */
        String str1 = "hello";
        String str2 = "hello";
        System.out.println(str1 == str2);

        String str3 = new String("hello");
        String str4 = new String("hello");
        System.out.println(str3 == str4);

    }
    /**
     * String类的一些常用方法及注意事项
     * @param args
     * 注意事项
     *      1.String是引用类型,内部并不存储字符串本身(引用value数组(引用字符数组) + hash 组成的对象)
     *      2.""引用起来的字符串也是String类型
     * 常见方法
     *      1.判断字符串长度 字符串.length(),求数组长度是length
     *      2.判断字符串是否为空 字符串.isEmpty()
     */
    public static void main2(String[] args) {
        //注意事项,1.
        String str1 = "hello";
        System.out.println(str1);

        String str2 = "world";
        System.out.println(str2);

        String str3 = str1;
        System.out.println(str3);

        //2.
        System.out.println("hello".length());

        //常用方法
        /**
         * length(),判断字符串长度,返回类型为:int
         */
        String str5 = "";
        System.out.println(str1.length());
        System.out.println(str5);

        /**
         * isEmpty(),判断字符串是否为空,返回类型为:boolean
         */
        System.out.println(str5.isEmpty());
    }
    /**
     * 常用构造方法
     * @param args
     *      1.常量字符串构造
     *      2.实例化构造
     *      3.字符数组构造
     * 注:java中存在很多重载构造方法,可以根据需求查表找构造方法使用即可
     */
    public static void main1(String[] args) {
        String str1 = "hello";
        System.out.println(str1);

        String str2 = new String("JAVA");
        System.out.println(str2);

        char[] array = {'w','o','r','l','d'};
        String str3 = new String(array);
        System.out.println(str3);
    }
}
